#include "dataContainer.h"
#include "plotter.h"
#include "graph.h"
#include <QFile>
#include <QTextStream>
#include <QStringList>
#include <iostream>
#include <QStandardItemModel>

//an atomic data
AtomicData::AtomicData(QDate &date) : QDate(date) {
	avgPrice = 0; minPrice = 0;
};

//single object
ObjectData::ObjectData( QString objName ) {
	name = objName;
}; 

// all data
DataContainer::DataContainer() {
};

int DataContainer::readFromCSV() {
	QFile *avgFile, *minFile;
	QTextStream *avgStream, *minStream;
	QStringList avgList, minList;
	
	//read AVG PRICE
	avgFile = new QFile("./data/avg_price.csv");
	if( !avgFile->open(QIODevice::ReadWrite | QIODevice::Text) ) return 1; //TODO error handling
	minFile = new QFile("./data/min_price.csv" );
	if( !minFile->open(QIODevice::ReadWrite | QIODevice::Text) ) return 1; //TODO error handling
	avgStream = new QTextStream(avgFile);
	minStream = new QTextStream(minFile);
	//read first string
	avgList = avgStream->readLine().split(",");
	minList = minStream->readLine().split(",");
	for( int i = 1; i < avgList.size(); i++ ) {
		if( avgList.at(i) != minList.at(i) ) {
			std::cout << "Mismatch in avg_price.csv and min_price.csv headers" << std::endl;
			return 1; //TODO: error handling 
		}
		nameIndex.append( avgList.at(i) );
		objects.append( new ObjectData( avgList.at(i) ) );
	}
	
	//read all other strings
	while( !avgStream->atEnd() ) {
		avgList = avgStream->readLine().split(",");
		minList = minStream->readLine().split(",");
		
		QDate date = QDate::fromString( avgList.at(0), "dd/MM/yyyy" );
		if( date != QDate::fromString( minList.at(0), "dd/MM/yyyy" ) ) {
			std::cout << "Mismatch in avg_price.csv and min_price.csv date lists" << std::endl;
			return 1;
		}
		dateIndex.append( date.toString("dd.MM.yyyy") );
		for( int i=1; i<avgList.size(); i++ )
			if( avgList.at(i) != "" || minList.at(i) != "" ) {
				//AtomicData * atomic = new AtomicData( date );
				////atomic->date = date;
				//if( avgList.at(i) != "" ) atomic->avgPrice = avgList.at(i).toDouble();
				//if( minList.at(i) != "" ) atomic->minPrice = minList.at(i).toDouble();
				//objects.at(i-1)->atomics.append( atomic );
				AtomicData atomic = AtomicData(date);
				if( avgList.at(i) != "" ) atomic.avgPrice = avgList.at(i).toDouble();
				if( minList.at(i) != "" ) atomic.minPrice = minList.at(i).toDouble();
				objects.at(i-1)->atomics.append( atomic );
			}
	}


	delete avgFile; delete minFile;
	delete avgStream; delete minStream;
	
	return 0;
};	

int DataContainer::fillAvgModel( QStandardItemModel * avgModel ) {
	for( int i=0; i<objects.size(); i++ )
		for( int j=0; j<objects.at(i)->atomics.size(); j++ ) {
			int row = dateIndex.indexOf( objects.at(i)->atomics.at(j).toString("dd.MM.yyyy") );
			int column = nameIndex.indexOf( objects.at(i)->name );
			QStandardItem *item = new QStandardItem( QString::number(objects.at(i)->atomics.at(j).avgPrice) );
			avgModel->setItem( row, column, item);
		}
	return 0;
}
int DataContainer::fillMinModel( QStandardItemModel * minModel ) {
	for( int i=0; i<objects.size(); i++ )
		for( int j=0; j<objects.at(i)->atomics.size(); j++ ) {
			int row = dateIndex.indexOf( objects.at(i)->atomics.at(j).toString("dd.MM.yyyy") );
			int column = nameIndex.indexOf( objects.at(i)->name );
			QStandardItem *item = new QStandardItem( QString::number(objects.at(i)->atomics.at(j).minPrice) );
			minModel->setItem( row, column, item);
		}
	return 0;
}

int DataContainer::priceToGraph(QString name, Graph* graph) {
	int index = nameIndex.indexOf( name );
	if( index == -1 ) { std::cout << "priceToGraph: no such name: " << name.toStdString() << std::endl; return 1; }
	int numPoints = objects.at(index)->atomics.size();
	graph->vals.resize( numPoints );
	graph->dates.resize( numPoints );
	for( int i=0; i<numPoints; i++ ) {
		graph->vals[i] = objects.at(index)->atomics.at(i).avgPrice;
		QString date = objects.at(index)->atomics.at(i).toString("dd.MM.yyyy");
		graph->dates[i] = dateIndex.indexOf( date );
	}
	return 0;
}

void DataContainer::comissionsToGraph(QDate date, Graph* graph) {
	int counter = 0;
	for( int i=0; i<objects.size(); i++ )
		//for( int j=0; j<objects.at(i)->atomics.size(); j++ )
			if( int k = objects.at(i)->atomics.indexOf( AtomicData(date) ) != -1 ) {
				double price = objects.at(i)->atomics.at(k).avgPrice;
				QDate lastDate = objects.at(i)->atomics.at( objects.at(i)->atomics.size()-1 );
				double ef_doh = (100.0/price)*( 365.0 / (date.daysTo( lastDate )-1))*100;
				graph->dates.append( counter );
				graph->vals.append( ef_doh );
				counter++;
			}
	//std::cout << counter << std::endl;
}
